'''
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * <p>
 * http:#www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
'''
from base.datatypes import TypeMapper
from base.graph.BlankNodeId import BlankNodeId
from base.graph.Node_Blank import Node_Blank
from base.graph.Node_Graph import Node_Graph
from base.graph.Node_Literal import Node_Literal
from base.graph.Node_Marker import Node_Marker
from base.graph.Node_Triple import Node_Triple
from base.graph.Node_URI import Node_URI
from base.graph.Node_Variable import Node_Variable
from base.graph.Triple import Triple
from base.graph.impl.LiteralLabelFactory import LiteralLabelFactory
from base.java.Objects import Objects


#import java.util.Objects;

#import org.apache.jena.datatypes.DatatypeFormatException;
#import org.apache.jena.datatypes.RDFDatatype;
#import org.apache.jena.datatypes.TypeMapper;
#import org.apache.jena.graph.impl.LiteralLabel;
#import org.apache.jena.graph.impl.LiteralLabelFactory;
#import org.apache.jena.sys.JenaSystem;

class NodeFactory:

    #TODO
    # JenaSystem.init()
    def __init__(self):
        pass

    # param String s
    # result static RDFDatatype
    @staticmethod
    def getType(s):
        if (s is None):
            return None
        return TypeMapper.getInstance().getSafeTypeByName(s)
    

    ''' Make a fresh blank node'''
    # param 
    # result static Node
    # def createBlankNode(self):
    #     return createBlankNode(BlankNodeId.create())
    

    ''' make a blank node with the specified label
    '''
    # param BlankNodeId id
    # result static Node
    @staticmethod
    def createBlankNode(id):
        if id is None:
            return Node_Blank(BlankNodeId.create())
        #Objects.requireNonNull(id, "Argument to NodeFactory.createBlankNode is null")
        if isinstance(id, str):
            id = BlankNodeId.create(id)
        return Node_Blank(id)
    

    ''' make a blank node with the specified label'''
    # param String string
    # result static Node
    # def createBlankNode(string):
    #     BlankNodeId id = BlankNodeId.create(string)
    #     return Node_Blank(id)
    

    ''' make a URI node with the specified URIref string'''
    # param String uri
    # result static Node
    @staticmethod
    def createURI(uri):
        Objects.requireNonNull(uri, "Argument to NodeFactory.createURI is null")
        return Node_URI(uri)
    

    ''' make a variable node with a given name'''
    # param String name
    # result static Node
    @staticmethod
    def createVariable(name):
        Objects.requireNonNull(name, "Argument to NodeFactory.createVariable is null")
        return Node_Variable(name)
    

    ''' make an extension node based on a string.'''
    # param String name
    # result static Node
    @staticmethod
    def createExt(name):
        Objects.requireNonNull(name, "Argument to NodeFactory.createExt is null")
        return Node_Marker(name)

    #这个方法结合了所有其他的方法，需要做参数判断
    #TODO 后续不需要实现这个方法 java中已经废弃这个，使用createLiteralByValue
    @staticmethod
    def createLiteral(lit, lex, lang, isXml, dtype):
        pass


    ''' make a literal node with the specified literal value
     * @deprecated Making nodes directly from:@link LiteralLabel may be removed.
    '''
    #@Deprecated
    # param LiteralLabel lit
    # result static Node
    # def createLiteral(lit):
    #     Objects.requireNonNull(lit, "Argument to NodeFactory.createLiteral is null")
    #     return Node_Literal(lit)
    

    # param String value
    # result static Node
    # def createLiteral(value):
    #     Objects.requireNonNull(value, "Argument to NodeFactory.createLiteral is null")
    #     return createLiteral(value, "", False)
    

    '''
     * make a literal with specified language and XMLishness. lexical form must
     * not be null.
     *
     * @param lex
     * @param lang
     * @param isXml
     *            If true then lit is exclusive canonical XML of type
     *            rdf:XMLLiteral, and no checking will be invoked.
     @deprecated To be removed.
    '''
    #@Deprecated
    # param String lex, String lang, boolean isXml
    # result static Node
    # def createLiteral(lex, lang, isXml):
    #     if (lex is None)
    #         throw new NullPointerException("null lexical form for literal")
    #     return createLiteral(LiteralLabelFactory.create(lex, lang, isXml))
    

    '''
     * Make a literal with specified language. lexical form must not be null.
     *
     * @param lex
     *            the lexical form of the literal
     * @param lang
     *            the optional language tag
    '''
    # param String lex, String lang
    # result static Node
    # def createLiteral(lex, lang):
    #     # Equivalent to create(lex, lang, false) except the XML flag is
    #     # hidden so client code does not see it unnecesarily.
    #     if (lex is None)
    #         throw new NullPointerException("null lexical form for literal")
    #     return createLiteral(LiteralLabelFactory.create(lex, lang))
    

    '''
     * Build a literal node from its lexical form. The lexical form will be
     * parsed now and the value stored. If the form is not legal this will throw
     * an exception.
     *
     * @param lex
     *            the lexical form of the literal
     * @param lang
     *            the optional language tag
     * @param dtype
     *            the type of the literal
     * @throws DatatypeFormatException
     *             if lex is not a legal form of dtype
    '''
    # param String lex, String lang, RDFDatatype dtype
    # result static Node
    # def createLiteral(lex, lang, dtype):
    #     return createLiteral(LiteralLabelFactory.createLiteralLabel(lex, lang, dtype))
    

    '''
     * Build a typed literal node from its lexical form. The lexical form will
     * be parsed now and the value stored. If the form is not legal this will
     * throw an exception.
     *
     * @param lex
     *            the lexical form of the literal
     * @param dtype
     *            the type of the literal
     * @throws DatatypeFormatException
     *             if lex is not a legal form of dtype
    '''
    # param String lex, RDFDatatype dtype
    # result static Node
    # def createLiteral(lex, dtype):
    #     return createLiteral(LiteralLabelFactory.create(lex, dtype))
    

    ''' Create a Node based on the value
     * If the value is a string we
     * assume this is intended to be a lexical form after all.
     * @param value
     *          The value, mapped according to registered types.
     * @param dtype
     *          RDF Datatype.
     * @return Node
     * @throws DatatypeFormatException
    '''
    # param Object value, RDFDatatype dtype
    # result static Node
    # @staticmethod
    # def createLiteralByValue(value, dtype):
    #     Objects.requireNonNull(value, "Argument 'value' to NodeFactory.createLiteralByValue is null")
    #     return Node_Literal(LiteralLabelFactory.createByValue(value, "", dtype))
    

    ''' Create a Node based on the value
     * If the value is a string we
     * assume this is intended to be a lexical form after all.
     * @param value
     *          The value, mapped according to registered types.
     * @param lang
     *          (optional) Language tag, if a string.
     * @param dtype
     *          RDF Datatype.
     * @return Node
     * @throws DatatypeFormatException
    '''
    # param Object value, String lang, RDFDatatype dtype
    # result static Node
    @staticmethod
    def createLiteralByValue(value, lang, dtype):
        Objects.requireNonNull(value, "Argument 'value' to NodeFactory.createLiteralByValue is null")
        return Node_Literal(LiteralLabelFactory.createByValue(value, lang, dtype))
    

    ''' Create a triple node (RDF-star)'''
    # param Node s, Node p, Node o
    # result static Node
    # @staticmethod
    # def createTripleNode(s, p, o):
    #     #Triple
    #     triple = Triple.create(s, p, o)
    #     return createTripleNode(triple)
    

    ''' Create a triple node (RDF-star)'''
    # param Triple triple
    # result static Node
    @staticmethod
    def createTripleNode(triple):
        return Node_Triple(triple)
    

    ''' Create a graph node. This is an N3-formula it is not a named graph (see "quad")'''
    # param Graph graph
    # result static Node
    @staticmethod
    def createGraphNode(graph):
        return Node_Graph(graph)
    

